<template>
  <div>
    <input ref="excelUploadInput" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick" />
    <!-- <div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
      Drop excel file here or
      <el-button :loading="initData.loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">导入Excel</el-button>
    </div> -->
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive } from 'vue'
import XLSX from 'xlsx'

// 使用报表导入示例：
// uploadExcel.value && uploadExcel.value.excelUploadInput.dispatchEvent(new MouseEvent('click'))

// import { ElMessage } from 'element-plus'

const props = defineProps({
  beforeUpload: {
    type: Function,
    default: ''
  },
  onSuccess: {
    type: Function,
    default: ''
  }
})
const initData = reactive({
  loading: false,
  excelData: {
    header: null,
    results: null,
    fileName: ''
  }
})

const excelUploadInput = ref(null)

const emits = defineEmits(['onSuccess'])

const generateData = (header: any, results: any) => {
  initData.excelData.header = header
  initData.excelData.results = results
  props.onSuccess && props.onSuccess(initData.excelData)
  emits('onSuccess', initData.excelData)
}

// const handleDragover = (e) => {
//   e.stopPropagation()
//   e.preventDefault()
//   e.dataTransfer.dropEffect = 'copy'
// }

// const handleDrop = (e) => {
//   e.stopPropagation()
//   e.preventDefault()
//   if (initData.loading) return
//   const files = e.dataTransfer.files
//   if (files.length !== 1) {
//     ElMessage.error('Only support uploading one file!')
//     return
//   }
//   const rawFile = files[0] // only use files[0]

//   if (!isExcel(rawFile)) {
//     ElMessage.error('Only supports upload .xlsx, .xls, .csv suffix files')
//     return false
//   }
//   upload(rawFile)
//   e.stopPropagation()
//   e.preventDefault()
// }

// const handleUpload = () => {
//   excelUploadInput.value.click()
// }

const handleClick = (e) => {
  const files = e.target.files
  const rawFile = files[0] // only use files[0]
  initData.excelData.fileName = rawFile.name
  if (!rawFile) return
  upload(rawFile)
}

const upload = (rawFile) => {
  excelUploadInput.value = null // fix can't select the same excel
  if (!props.beforeUpload) {
    readerData(rawFile)
    return
  }
  const before = props.beforeUpload(rawFile)
  if (before) {
    readerData(rawFile)
  }
}

const readerData = (rawFile) => {
  initData.loading = true
  return new Promise<void>((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      const data = e.target.result
      const fixedData = fixData(data)
      const workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
      const firstSheetName = workbook.SheetNames[0]
      const worksheet = workbook.Sheets[firstSheetName]
      const header = getHeaderRow(worksheet)
      const results = XLSX.utils.sheet_to_json(worksheet)
      generateData(header, results)
      initData.loading = false
      resolve()
    }
    reader.readAsArrayBuffer(rawFile)
  })
}
const fixData = (data) => {
  let o = ''
  let l = 0
  const w = 10240
  for (; l < data.byteLength / w; ++l) {
    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
  }
  o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
  return o
}
const getHeaderRow = (sheet) => {
  const headers = []
  const range = XLSX.utils.decode_range(sheet['!ref'])
  let C
  const R = range.s.r
  /* start in the first row */
  for (C = range.s.c; C <= range.e.c; ++C) {
    /* walk every column in the range */
    const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
    /* find the cell in the first row */
    let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
    if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
    headers.push(hdr)
  }
  return headers
}

const isExcel = (file) => {
  return /\.(xlsx|xls|csv)$/.test(file.name)
}
defineExpose({
  excelUploadInput
})
</script>

<style lang="scss" scoped>
.excel-upload-input {
  z-index: -9999;
  display: none;
}

.drop {
  position: relative;
  width: 600px;
  height: 160px;
  margin: 0 auto;
  font-size: 24px;
  line-height: 160px;
  color: #bbb;
  text-align: center;
  border: 2px dashed #bbb;
  border-radius: 5px;
}
</style>
